<?php

define('IN_API', true);
require_once '../../framework/bootstrap.inc.php';
load()->model('reply');
load()->model('attachment');
load()->app('common');
load()->classs('wesession');
if (empty($id)) {
	$id = intval($_GPC["id"]);
}
if (!empty($id)) {
	$_W["account"] = uni_fetch($id);
}
if (empty($_W["account"])) {
	exit("initial error hash or id");
}
if (empty($_W["account"]["token"])) {
	exit("initial missing token");
}
$_W["debug"] = intval($_GPC["debug"]);
$_W["acid"] = $_W["account"]["acid"];
$_W["uniacid"] = $_W["account"]["uniacid"];
$_W["uniaccount"] = uni_fetch($_W["uniacid"]);
$_W["account"]["groupid"] = $_W["uniaccount"]["groupid"];
$_W["attachurl"] = attachment_set_attach_url();
$engine = new WeEngine();
if (!empty($_W["setting"]["copyright"]["status"])) {
	$engine->died("抱歉，站点已关闭，关闭原因：" . $_W["setting"]["copyright"]["reason"]);
}
if (!empty($_W["uniaccount"]["endtime"]) && $_W["uniaccount"]["endtime"] < TIMESTAMP) {
	$engine->died("抱歉，您的公众号已过期，请及时联系管理员");
}
if ($_W["isajax"] && $_W["ispost"] && $_GPC["flag"] == 1) {
	$engine->encrypt();
}
if ($_W["isajax"] && $_W["ispost"] && $_GPC["flag"] == 2) {
	$engine->decrypt();
}
$_W["isajax"] = false;
$engine->start();
class WeEngine
{
	private $account;
	private $openLog = false;
	public $message = array();
	public function __construct()
	{
		global $_W;
		$this->account = WeAccount::create($_W["account"]);
		$this->openLog = true;
	}
	public function encrypt()
	{
		global $_W;
		if (empty($this->{"account"})) {
			exit("Miss Account.");
		}
		$timestamp = TIMESTAMP;
		$nonce = random(5);
		$token = $_W["account"]["token"];
		$signkey = array($token, TIMESTAMP, $nonce);
		sort($signkey, SORT_STRING);
		$signString = implode($signkey);
		$signString = sha1($signString);
		$_GET["timestamp"] = $timestamp;
		$_GET["nonce"] = $nonce;
		$_GET["signature"] = $signString;
		$postStr = file_get_contents("php://input");
		if (!empty($_W["account"]["encodingaeskey"]) && strlen($_W["account"]["encodingaeskey"]) == 43 && !empty($_W["account"]["key"]) && $_W["setting"]["development"] != 1) {
			$data = $this->account->encryptMsg($postStr);
			$array = array("encrypt_type" => "aes", "timestamp" => $timestamp, "nonce" => $nonce, "signature" => $signString, "msg_signature" => $data[0], "msg" => $data[1]);
		} else {
			$data = array("", "");
			$array = array("encrypt_type" => "", "timestamp" => $timestamp, "nonce" => $nonce, "signature" => $signString, "msg_signature" => $data[0], "msg" => $data[1]);
		}
		exit(json_encode($array));
	}
	public function decrypt()
	{
		global $_W;
		if (empty($this->{"account"})) {
			exit("Miss Account.");
		}
		$postStr = file_get_contents("php://input");
		if (!empty($_W["account"]["encodingaeskey"]) && strlen($_W["account"]["encodingaeskey"]) == 43 && !empty($_W["account"]["key"]) && $_W["setting"]["development"] != 1) {
			$resp = $this->account->local_decryptMsg($postStr);
		} else {
			$resp = $postStr;
		}
		exit($resp);
	}
	public function start()
	{
		global $_W;
		if (empty($this->{"account"})) {
			exit("Miss Account.");
		}
		if (!$this->account->checkSign()) {
			exit("Check Sign Fail.");
		}
		if (strtolower($_SERVER["REQUEST_METHOD"]) == "get") {
			$row = array();
			$row["isconnect"] = 1;
			@pdo_update('account', $row, array("acid" => $_W["acid"]));
			@cache_delete("uniaccount:{$_W["uniacid"]}");
			exit(htmlspecialchars($_GET["echostr"]));
		}
		if (strtolower($_SERVER["REQUEST_METHOD"]) == "post") {
			$postStr = file_get_contents("php://input");
			$message = json_decode($postStr, true);
			$message["custom"] = true;
			$this->message = $message;
			if (empty($message)) {
				$this->logging("waring", "Request Failed");
				exit('Request Failed');
			}
			$_W["openid"] = $message["from"];
			$_W["fans"] = array("from_user" => $_W["openid"]);
			$sessionid = md5($message["from"] . $message["to"] . $_W["uniacid"]);
			session_id($sessionid);
			WeSession::start($_W["uniacid"], $_W["openid"]);
			$_SESSION["openid"] = $_W["openid"];
			$par = array("message" => $message, "module" => "asterye_waimaixia_plugin_one", "rule" => "-1");
			$resp = $this->process($par);
			if ($resp !== "success") {
				$mapping = array("[from]" => $this->message["from"], "[to]" => $this->message["to"], "[rule]" => $this->params["rule"]);
				$resp = str_replace(array_keys($mapping), array_values($mapping), $resp);
			}
			ob_clean();
			ob_start();
			echo $resp;
			ob_end_flush();
			exit;
		} else {
			exit('Request Failed');
		}
	}
	private function process($param)
	{
		$processor = WeUtility::createModuleProcessor($param["module"]);
		$processor->message = $param["message"];
		$processor->rule = $param["rule"];
		$processor->reply_type = $param["reply_type"];
		$processor->priority = intval($param["priority"]);
		$processor->inContext = $param["context"] === true;
		$response = $processor->respond();
		if (empty($response)) {
			return false;
		}
		return $response;
	}
	public function died($content = "success")
	{
		exit($content);
	}
	public function checkSign()
	{
		$token = $this->account["token"];
		$signkey = array($token, $_GET["timestamp"], $_GET["nonce"]);
		sort($signkey, SORT_STRING);
		$signString = implode($signkey);
		$signString = sha1($signString);
		return $signString == $_GET["signature"];
	}
}